#include <Windows.h>
#include <gl/gl.h>
#include <assert.h>
#include "GlShowlistManager.h"

using namespace std;
using namespace OOPUtils;
using namespace GlBase;

GlShowlistManager::GlShowlistManager ()
{
	ShowListInfo head = {1, ""};
	_showListContainer.push_back (head);
}

GlShowlistManager::~GlShowlistManager ()
{
	glDeleteLists (1, _showListContainer.size () - 1);
}

void GlShowlistManager::createNewList (string name, GLenum mode)
		throw (ShowlistFullException &)
{
	// Get the first free node in container
	unsigned int firstFree = _showListContainer[0].nextFree;
	if (firstFree == 0) // Cannot add any more show lists
		OOPTHROW (ShowlistFullException);

	assert (!glIsList (firstFree));
	assert (firstFree <= _showListContainer.size ());

	ShowListInfo newShowListInfo = {0, name};

	if (firstFree == _showListContainer.size ()) // no free nodes in container
	{
		_showListContainer[0].nextFree = firstFree + 1;
		_showListContainer.push_back (newShowListInfo);
	}
	else
	{
		_showListContainer[0].nextFree = _showListContainer[firstFree].nextFree;
		_showListContainer[firstFree] = newShowListInfo;
	}

	glNewList (firstFree, mode);
}

unsigned int GlShowlistManager::getList (std::string name)
		throw (ShowlistNotFoundException &)
{
	for (size_t i = 0; i < _showListContainer.size (); ++i)
		if (name == _showListContainer[i].name)
			return i;
	OOPTHROW (ShowlistNotFoundException);
}

void GlShowlistManager::deleteList (string name)
{
	GLuint showListId = getList (name);
	if (showListId == 0) return;
	assert (glIsList (showListId));
	glDeleteLists (showListId, 1);

	_showListContainer[showListId].nextFree = _showListContainer[0].nextFree;
	_showListContainer[showListId].name = "";
	_showListContainer[0].nextFree = showListId;
}